use std::sync::{
    atomic::{AtomicU64, Ordering},
    Arc, Mutex,
};
use std::thread;
use std::time::Duration;

pub const N_TIMES: u64 = 10_000_000;
pub const N_THREADS: usize = 10;

pub fn run_atomic(n_times: u64, n_threads: usize) {
    let counter = Arc::new(AtomicU64::new(0));

    thread::scope(|scope| {
        for _ in 0..n_threads {
            let counter = counter.clone();
            scope.spawn(move || {
                for _ in 0..n_times {
                    counter.fetch_add(1, Ordering::Relaxed);
                }
            });
        }
    });

    assert_eq!(
        n_times * n_threads as u64,
        counter.load(Ordering::Relaxed),
        "Atomic counter mismatch"
    );
}

pub fn run_mutex(n_times: u64, n_threads: usize) {
    let counter = Arc::new(Mutex::new(0u64));

    thread::scope(|scope| {
        for _ in 0..n_threads {
            let counter = counter.clone();
            scope.spawn(move || {
                for _ in 0..n_times {
                    let mut guard = counter.lock().unwrap();
                    *guard += 1;
                }
            });
        }
    });

    assert_eq!(
        n_times * n_threads as u64,
        *counter.lock().unwrap(),
        "Mutex counter mismatch"
    );
}

// 可选：加一个轻量的 warm-up 帮助 bench 稳定
pub fn warm_up() {
    run_atomic(1000, 2);
    run_mutex(1000, 2);
    thread::sleep(Duration::from_millis(50));
}